summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2016-12-13 12:46:09 -0700
committerMike Buland <eichlan@xagasoft.com>2016-12-13 12:46:09 -0700
commit7e0edb6c2db17c87415fbd041ef7add9dfb467e5 (patch)
tree2feddf5d1dde80d97b2eefdd299cbebc0d2e30d4
parent5d59aa3e9dffe2912215335ce0b76c67ebbe5a4e (diff)
downloadclic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.tar.gz
clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.tar.bz2
clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.tar.xz
clic-7e0edb6c2db17c87415fbd041ef7add9dfb467e5.zip
Corrected negation and single value parse bugs.
Discovered arithmetic bug in the Number class, -4 + 5 is coming back as -1, not 1. It's getting the sign wrong somehow. I'll have to hunt that down.
-rw-r--r--src/lexer.cpp12
-rw-r--r--src/parser.cpp24
-rw-r--r--src/scriptengine.cpp70
-rw-r--r--src/token.cpp7
-rw-r--r--src/token.h10
-rw-r--r--src/unitnumber.cpp4
6 files changed, 83 insertions, 44 deletions
diff --git a/src/lexer.cpp b/src/lexer.cpp
index 87d603a..9c8b36a 100644
--- a/src/lexer.cpp
+++ b/src/lexer.cpp
@@ -96,7 +96,13 @@ Token Lexer::nextTokenNormal()
96 { 96 {
97 sTmp->append( sBuf[iBufPos] ); 97 sTmp->append( sBuf[iBufPos] );
98 } 98 }
99 return Token( Token::tCommand, sTmp ); 99 if( *sTmp == "quit" || *sTmp == "exit" )
100 return Token( Token::tCmdExit );
101 else if( *sTmp == "scale" )
102 return Token( Token::tCmdScale );
103 else if( *sTmp == "radix" )
104 return Token( Token::tCmdRadix );
105 return Token( Token::tCmdExtended, sTmp );
100 } 106 }
101 break; 107 break;
102 108
@@ -196,13 +202,13 @@ Token Lexer::nextTokenCommand()
196 if( iBufPos >= sBuf.getSize() ) 202 if( iBufPos >= sBuf.getSize() )
197 { 203 {
198 iBufPos = -1; 204 iBufPos = -1;
199 return Token( Token::tEndOfLine ); 205 return Token( Token::tCmdEndParams );
200 } 206 }
201 207
202 if( iBufPos < 0 ) 208 if( iBufPos < 0 )
203 { 209 {
204 if( rIn.isEos() ) 210 if( rIn.isEos() )
205 return Token( Token::tEndOfInput ); 211 return Token( Token::tCmdEndParams );
206 212
207 sBuf = rIn.readLine(); 213 sBuf = rIn.readLine();
208 if( sBuf.getSize() == 0 ) 214 if( sBuf.getSize() == 0 )
diff --git a/src/parser.cpp b/src/parser.cpp
index 982c342..8e30d24 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -8,7 +8,7 @@
8#include <bu/sio.h> 8#include <bu/sio.h>
9#include <stdlib.h> 9#include <stdlib.h>
10 10
11// #define DEBUG_MODE 1 11//#define DEBUG_MODE 1
12#ifdef DEBUG_MODE 12#ifdef DEBUG_MODE
13#define DBG( x ) { x; } (void)0 13#define DBG( x ) { x; } (void)0
14#else 14#else
@@ -161,6 +161,7 @@ void Parser::exprP()
161 return; 161 return;
162 } 162 }
163 163
164 DBG( Bu::sio << "exprP on " << lex[0] << Bu::sio.nl );
164 switch( lex[0].eType ) 165 switch( lex[0].eType )
165 { 166 {
166 case Token::tNumber: 167 case Token::tNumber:
@@ -188,7 +189,7 @@ void Parser::exprP()
188 case Token::tMinus: 189 case Token::tMinus:
189 lex.nextToken(); 190 lex.nextToken();
190 exprP(); 191 exprP();
191 shift( Token( Token::tNegate ) ); 192 shift( Token( Token::tNegate ) );
192 reduce(); 193 reduce();
193 break; 194 break;
194 } 195 }
@@ -196,7 +197,7 @@ void Parser::exprP()
196 197
197void Parser::statement() 198void Parser::statement()
198{ 199{
199 if( lex[0].eType == Token::tCommand ) 200 if( (lex[0].eType&Token::mMetaCmd) )
200 { 201 {
201 lex.setMode( Lexer::modeCommand ); 202 lex.setMode( Lexer::modeCommand );
202 output( lex[0] ); 203 output( lex[0] );
@@ -309,7 +310,8 @@ case Token::tCommand:
309 310
310void Parser::shift( const Token &t ) 311void Parser::shift( const Token &t )
311{ 312{
312 if( (t.eType&(Token::mMetaOperator)) || t.eType==Token::tCloseParen ) 313 if( (t.eType&(Token::mMetaOperator|Token::mMetaAltOp)) ||
314 t.eType==Token::tCloseParen )
313 tsTerminal.push( t ); 315 tsTerminal.push( t );
314 else 316 else
315 tsNonTerminal.push( t ); 317 tsNonTerminal.push( t );
@@ -317,9 +319,20 @@ void Parser::shift( const Token &t )
317 319
318void Parser::reduce() 320void Parser::reduce()
319{ 321{
320 if( tsTerminal.isEmpty() || tsNonTerminal.peek().eType == Token::tOpenParen ) 322 if( tsTerminal.isEmpty() )
323 {
324 DBG( Bu::sio << "reduce: terminal stack empty." << Bu::sio.nl );
325 if( !tsNonTerminal.isEmpty() )
326 {
327 DBG( Bu::sio << " : non-terminal stack non-empty, pushing item." << Bu::sio.nl );
328 output( tsNonTerminal.peekPop() );
329 }
330 return;
331 }
332 if( tsNonTerminal.peek().eType == Token::tOpenParen )
321 return; 333 return;
322 Token tOp = tsTerminal.peekPop(); 334 Token tOp = tsTerminal.peekPop();
335 DBG( Bu::sio << "recuding on " << tOp << Bu::sio.nl );
323 switch( tOp.eType ) 336 switch( tOp.eType )
324 { 337 {
325 /* 338 /*
@@ -416,7 +429,6 @@ int Parser::getPriority( Token::Type eType )
416 { 429 {
417 case Token::tNumber: 430 case Token::tNumber:
418 case Token::tVariable: 431 case Token::tVariable:
419 case Token::tCommand:
420 return 0; 432 return 0;
421 433
422 case Token::tPlus: 434 case Token::tPlus:
diff --git a/src/scriptengine.cpp b/src/scriptengine.cpp
index b65db70..e4c5c2e 100644
--- a/src/scriptengine.cpp
+++ b/src/scriptengine.cpp
@@ -39,6 +39,12 @@ void ScriptEngine::exec( Expression *pExpr )
39 39
40 for( Expression::iterator i = pExpr->begin(); i; i++ ) 40 for( Expression::iterator i = pExpr->begin(); i; i++ )
41 { 41 {
42// Bu::sio << (*i).eType << " - " << sNums << Bu::sio.nl;
43 if( ((*i).eType&Token::mMetaCmd) )
44 {
45 command( i );
46 continue;
47 }
42 switch( (*i).eType ) 48 switch( (*i).eType )
43 { 49 {
44 case Token::tNumber: 50 case Token::tNumber:
@@ -96,10 +102,6 @@ void ScriptEngine::exec( Expression *pExpr )
96 case Token::tNegate: 102 case Token::tNegate:
97 sNums.push( -sNums.peekPop() ); 103 sNums.push( -sNums.peekPop() );
98 break; 104 break;
99
100 case Token::tCommand:
101 command( i );
102 return;
103 } 105 }
104 } 106 }
105 107
@@ -109,35 +111,39 @@ void ScriptEngine::exec( Expression *pExpr )
109 111
110void ScriptEngine::command( Expression::iterator &i ) 112void ScriptEngine::command( Expression::iterator &i )
111{ 113{
112 Bu::String sCmd = *(*i).sVal; 114 switch( (*i).eType )
113 if( sCmd == "exit" || sCmd == "quit" )
114 { 115 {
115 bRunning = false; 116 case Token::tCmdExit:
116 return; 117 bRunning = false;
117 }
118 else if( sCmd == "scale" )
119 {
120 if( !(++i) )
121 {
122 if( sigError.isSet() )
123 sigError("You must provide a positive integer.");
124 return; 118 return;
125 } 119
126 int32_t iScale = strtol( (*i).sVal->getStr(), 0, 10 ); 120 case Token::tCmdScale:
127 if( iScale < 0 ) 121 {
128 { 122 if( !(++i) )
129 if( sigError.isSet() ) 123 {
130 sigError("You must provide a positive integer."); 124 if( sigError.isSet() )
131 return; 125 sigError("You must provide a positive integer.");
132 } 126 return;
133 if( sigMessage.isSet() ) 127 }
134 sigMessage(Bu::String("Changed scale to: %1").arg( iScale )); 128 int32_t iScale = strtol( (*i).sVal->getStr(), 0, 10 );
135 for( VarHash::iterator i = hVarState.begin(); i; i++ ) 129 if( iScale < 0 )
136 (*i).setScale( iScale ); 130 {
137 } 131 if( sigError.isSet() )
138 else if( sCmd == "radix" ) 132 sigError("You must provide a positive integer.");
139 { 133 return;
140 } 134 }
135 if( sigMessage.isSet() )
136 sigMessage(Bu::String("Changed scale to: %1").arg( iScale ));
137 for( VarHash::iterator i = hVarState.begin(); i; i++ )
138 (*i).setScale( iScale );
139 }
140 break;
141
142 case Token::tCmdRadix:
143 break;
144
145 case Token::tCmdExtended:
146 /*
141 else if( sCmd == "vars" ) 147 else if( sCmd == "vars" )
142 { 148 {
143 } 149 }
@@ -146,6 +152,8 @@ void ScriptEngine::command( Expression::iterator &i )
146 } 152 }
147 else 153 else
148 { 154 {
155 }*/
156 break;
149 } 157 }
150} 158}
151 159
diff --git a/src/token.cpp b/src/token.cpp
index 0c7bda1..ff04e94 100644
--- a/src/token.cpp
+++ b/src/token.cpp
@@ -45,8 +45,9 @@ Token::~Token()
45 break; 45 break;
46 46
47 case tVariable: 47 case tVariable:
48 case tCommand:
49 case tString: 48 case tString:
49 case tCmdExtended:
50 case tCmdParam:
50 delete sVal; 51 delete sVal;
51 break; 52 break;
52 53
@@ -64,8 +65,9 @@ Token &Token::operator=( const Token &rhs )
64 break; 65 break;
65 66
66 case tVariable: 67 case tVariable:
67 case tCommand:
68 case tString: 68 case tString:
69 case tCmdExtended:
70 case tCmdParam:
69 delete sVal; 71 delete sVal;
70 break; 72 break;
71 73
@@ -87,7 +89,6 @@ Bu::Formatter &operator<<( Bu::Formatter &f, Token::Type eType )
87 { 89 {
88 case Token::tNumber: return f << "num"; 90 case Token::tNumber: return f << "num";
89 case Token::tVariable: return f << "var"; 91 case Token::tVariable: return f << "var";
90 case Token::tCommand: return f << "cmd";
91 case Token::tPlus: return f << "+"; 92 case Token::tPlus: return f << "+";
92 case Token::tMinus: return f << "-"; 93 case Token::tMinus: return f << "-";
93 case Token::tDivide: return f << "/"; 94 case Token::tDivide: return f << "/";
diff --git a/src/token.h b/src/token.h
index 5bede41..4d738ec 100644
--- a/src/token.h
+++ b/src/token.h
@@ -15,7 +15,7 @@ public:
15 { 15 {
16 tNumber = 0x1001, 16 tNumber = 0x1001,
17 tVariable = 0x2002, 17 tVariable = 0x2002,
18 tCommand = 0x2003, 18 //tCommand = 0x2003,
19 tPlus = 0x4004, 19 tPlus = 0x4004,
20 tMinus = 0x4005, 20 tMinus = 0x4005,
21 tDivide = 0x4006, 21 tDivide = 0x4006,
@@ -34,12 +34,20 @@ public:
34 tUninitialized = 0x0110, 34 tUninitialized = 0x0110,
35 tComputedValue = 0x0111, 35 tComputedValue = 0x0111,
36 36
37 tCmdExit = 0x0201,
38 tCmdScale = 0x0202,
39 tCmdRadix = 0x0203,
40 tCmdExtended = 0x02f0,
41 tCmdParam = 0x02f1,
42 tCmdEndParams = 0x02f2,
43
37 44
38 mMetaNumber = 0x1000, 45 mMetaNumber = 0x1000,
39 mMetaString = 0x2000, 46 mMetaString = 0x2000,
40 mMetaOperator = 0x4000, 47 mMetaOperator = 0x4000,
41 mMetaAltOp = 0x8000, 48 mMetaAltOp = 0x8000,
42 mMetaMeta = 0x0100, 49 mMetaMeta = 0x0100,
50 mMetaCmd = 0x0200
43 }; 51 };
44 52
45 Token(); 53 Token();
diff --git a/src/unitnumber.cpp b/src/unitnumber.cpp
index d213ed7..c316d4b 100644
--- a/src/unitnumber.cpp
+++ b/src/unitnumber.cpp
@@ -89,6 +89,10 @@ void UnitNumber::number1()
89 mathTest("1000902491523000321", *, "3004392012498000700", 89 mathTest("1000902491523000321", *, "3004392012498000700",
90 "3007103450821050020096034077958224700"); 90 "3007103450821050020096034077958224700");
91 91
92 mathTest("-4", -, "5", "-9");
93 mathTest("-4", -, "-5", "1");
94 mathTest("-4", +, "5", "1");
95 mathTest("5", +, "-4", "1");
92 mathTest("-872", +, "123", "-749"); 96 mathTest("-872", +, "123", "-749");
93 mathTest("728", +, "-51", "677"); 97 mathTest("728", +, "-51", "677");
94 mathTest("44", +, "-55", "-11"); 98 mathTest("44", +, "-55", "-11");